package fr.asip.cps3.exemple.controleurs;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Vector;

import org.apache.log4j.Logger;

import fr.asip.cps3.exemple.modele.Application;
import fr.asip.cps3.exemple.modele.MenuApplication;
import fr.asip.cps3.exemple.modele.exceptions.ExceptionControleur;
import fr.asip.cps3.exemple.modele.exceptions.ExceptionProgrammeExemple;
import fr.asip.cps3.exemple.modele.exceptions.ExceptionTraitement;
import fr.asip.cps3.exemple.modele.resultats.Resultat;
import fr.asip.cps3.exemple.modele.resultats.ResultatSignatureFichier;
import fr.asip.cps3.exemple.modele.resultats.ResultatSignatureMessage;
import fr.asip.cps3.exemple.modele.traitements.fonctionsPKCS11.empreintes.GenererEmpreinteFichier;
import fr.asip.cps3.exemple.modele.traitements.fonctionsPKCS11.empreintes.GenererEmpreinteMessage;
import fr.asip.cps3.exemple.modele.traitements.fonctionsPKCS11.generationaleatoire.GenerationSeed;
import fr.asip.cps3.exemple.modele.traitements.fonctionsPKCS11.objets.CreerObjet;
import fr.asip.cps3.exemple.modele.traitements.fonctionsPKCS11.objets.ModificationAttributObjet;
import fr.asip.cps3.exemple.modele.traitements.fonctionsPKCS11.sessions.Authentifier;
import fr.asip.cps3.exemple.modele.traitements.fonctionsPKCS11.signature.GenererSignatureFichier;
import fr.asip.cps3.exemple.modele.traitements.fonctionsPKCS11.signature.GenererSignatureMessage;
import fr.asip.cps3.exemple.modele.traitements.fonctionsPKCS11.slotscartes.InitPIN;
import fr.asip.cps3.exemple.modele.traitements.fonctionsPKCS11.slotscartes.ModifPIN;
import fr.asip.cps3.exemple.modele.traitements.fonctionsPKCS11.verifications.VerifierSignatureFichier;
import fr.asip.cps3.exemple.modele.traitements.fonctionsPKCS11.verifications.VerifierSignatureMessage;
import fr.asip.cps3.exemple.modele.traitements.util.TraitementsUtil;
import fr.asip.cps3.exemple.vues.ecrans.EcranUtil;
import fr.asip.cps3.exemple.vues.ecrans.saisie.Saisie;
import fr.asip.cps3.exemple.vues.ecrans.saisie.Saisie1PIN;
import fr.asip.cps3.exemple.vues.ecrans.saisie.Saisie2PIN;
import fr.asip.cps3.exemple.vues.ecrans.saisie.Saisie3PIN;
import fr.asip.cps3.exemple.vues.ecrans.saisie.SaisieFichier;
import fr.asip.cps3.exemple.vues.ecrans.saisie.SaisieFichierSignature;
import fr.asip.cps3.exemple.vues.ecrans.saisie.SaisieFiltreObjet;
import fr.asip.cps3.exemple.vues.ecrans.saisie.SaisieMessage;
import fr.asip.cps3.exemple.vues.ecrans.saisie.SaisieMessageSignature;
import fr.asip.cps3.exemple.vues.ecrans.saisie.SaisieObjet;
import fr.asip.cps3.exemple.vues.ecrans.saisie.SaisieSeed;

/**
 * Classe d'intéraction entre les écrans de saisies et le modèle
 *
 */
public class EcranControleur {

	/**
	 * Le loggeur
	 */
	 private static Logger log = Logger.getLogger(EcranControleur.class);	
	
	/**
	 * Exécute l'opération associée à la saisie effectuée
	 * @param application L'application
	 * @param saisie Ecran de saisie
	 */
	public static void executeOperation(Application application,Saisie saisie) {
		
		if(application != null && saisie != null) {
			
			try {

				switch(saisie.getType()) {
				
					//############//
					//# SESSIONS #//
					//############//
	
					case EcranUtil.TYPE_ECRAN_INIT_CODE_PORTEUR:
					case EcranUtil.TYPE_ECRAN_MODIF_CODE_PORTEUR:
					case EcranUtil.TYPE_ECRAN_AUTHENTIFICATION_UTILISATEUR:
					case EcranUtil.TYPE_ECRAN_AUTHENTIFICATION_SO:
						executeOperationP11Sessions(application,saisie);
						break;
	
					//##########//
					//# OBJETS #//
					//##########//
						
					case EcranUtil.TYPE_ECRAN_CREATION_OBJETS:
					case EcranUtil.TYPE_ECRAN_MODIFICATION_OBJETS:
					case EcranUtil.TYPE_ECRAN_RECHERCHE_OBJETS:
						executeOperationP11Objets(application,saisie);
						break;
						
					//##############//
					//# EMPREINTES #//
					//##############//
						
					case EcranUtil.TYPE_ECRAN_GENERATION_EMPREINTE_MESSAGE:
					case EcranUtil.TYPE_ECRAN_GENERATION_EMPREINTE_FICHIER:
						executeOperationP11Empreintes(application,saisie);
						break;
	
						
					//##############//
					//# SIGNATURES #//
					//##############//
						
					case EcranUtil.TYPE_ECRAN_GENERATION_SIGNATURE_MESSAGE:
					case EcranUtil.TYPE_ECRAN_GENERATION_SIGNATURE_FICHIER:
						executeOperationP11Signatures(application,saisie);
						break;
	
					//###########################//
					//# VERIFICATION SIGNATURES #//
					//###########################//
						
					case EcranUtil.TYPE_ECRAN_VERIFICATION_SIGNATURE_MESSAGE:
					case EcranUtil.TYPE_ECRAN_VERIFICATION_SIGNATURE_FICHIER:					
						executeOperationP11Verifications(application,saisie);
						break;					
						
					//########################//
					//# GENERATION ALEATOIRE #//
					//########################//
					
					case EcranUtil.TYPE_ECRAN_GENERATION_AVEC_SEED:
						executeOperationP11GenerationAleatoire(application,saisie);
						break;	
						
					default:
						log.error("Type d'écran inconnu");
						throw new ExceptionControleur(ExceptionProgrammeExemple.TYPE_CONTROLEUR_ECRAN,"Une erreur inattendue est survenue");
	
				}

				// Déclenche l'affichage de la mise à jour des menus
				application.declencheMAJMenus();				
				
			} catch (ExceptionProgrammeExemple e) {
				
				// Demande d'affichage de l'exception
				application.notifieException(e);
				
			} catch (Throwable t) {
				
				log.error("Une erreur inattendue est survenue : "+ExceptionProgrammeExemple.getStacktrace(t));				
				// Demande d'affichage de l'exception
				application.notifieException(new ExceptionControleur(ExceptionProgrammeExemple.TYPE_CONTROLEUR_ECRAN,"Une erreur inattendue est survenue"));
				
			}
			
		} else {
			
			log.error("L'application et/ou l'écran de saisie est nul");
			
			// Demande d'affichage de l'exception (si possible)
			if(application != null)
				application.notifieException(new ExceptionControleur(ExceptionProgrammeExemple.TYPE_CONTROLEUR_ECRAN,"Une erreur inattendue est survenue"));	
			
		}
	}
	
	/**
	 * Valide la saisie utilisateur
	 * @param application L'application
	 * @param saisie Ecran de saisie
	 * @return Liste des problèmes de saisie
	 */
	public static Vector<String> valideSaisie(Application application,Saisie saisie) {
		
		Vector<String> problemesSaisie = new Vector<String>();
		
		if(application != null && saisie != null) {
			
			try {

				switch(saisie.getType()) {
				
					//############//
					//# SESSIONS #//
					//############//
	
					case EcranUtil.TYPE_ECRAN_INIT_CODE_PORTEUR:
					case EcranUtil.TYPE_ECRAN_MODIF_CODE_PORTEUR:
					case EcranUtil.TYPE_ECRAN_AUTHENTIFICATION_UTILISATEUR:
					case EcranUtil.TYPE_ECRAN_AUTHENTIFICATION_SO:
						return valideSaisieP11Sessions(application,saisie);

	
					//##########//
					//# OBJETS #//
					//##########//
						
					case EcranUtil.TYPE_ECRAN_CREATION_OBJETS:
					case EcranUtil.TYPE_ECRAN_MODIFICATION_OBJETS:
						return valideSaisieP11Objets(application,saisie);
						
					//##############//
					//# EMPREINTES #//
					//##############//
						
					case EcranUtil.TYPE_ECRAN_GENERATION_EMPREINTE_MESSAGE:
					case EcranUtil.TYPE_ECRAN_GENERATION_EMPREINTE_FICHIER:
						return valideSaisieP11Empreintes(application,saisie);
						
					//##############//
					//# SIGNATURES #//
					//##############//
						
					case EcranUtil.TYPE_ECRAN_GENERATION_SIGNATURE_MESSAGE:
					case EcranUtil.TYPE_ECRAN_GENERATION_SIGNATURE_FICHIER:
						return valideSaisieP11Signatures(application,saisie);
	
					//###########################//
					//# VERIFICATION SIGNATURES #//
					//###########################//
						
					case EcranUtil.TYPE_ECRAN_VERIFICATION_SIGNATURE_MESSAGE:
					case EcranUtil.TYPE_ECRAN_VERIFICATION_SIGNATURE_FICHIER:					
						return valideSaisieP11Verifications(application,saisie);
						
					//########################//
					//# GENERATION ALEATOIRE #//
					//########################//
					
					case EcranUtil.TYPE_ECRAN_GENERATION_AVEC_SEED:
						return valideSaisieP11GenerationAleatoire(application,saisie);
						
					default:
						log.error("Type d'écran inconnu");
						throw new ExceptionControleur(ExceptionProgrammeExemple.TYPE_CONTROLEUR_ECRAN,"Une erreur inattendue est survenue");
	
				}

			} catch (ExceptionProgrammeExemple e) {
				
				// Demande d'affichage de l'exception
				application.notifieException(e);
				
			} catch (Throwable t) {
				
				log.error("Une erreur inattendue est survenue : "+ExceptionProgrammeExemple.getStacktrace(t));				
				// Demande d'affichage de l'exception
				application.notifieException(new ExceptionControleur(ExceptionProgrammeExemple.TYPE_CONTROLEUR_ECRAN,"Une erreur inattendue est survenue"));
				
			}
			
		} else {
			
			log.error("L'application et/ou l'écran de saisie est nul");
			
			// Demande d'affichage de l'exception (si possible)
			if(application != null)
				application.notifieException(new ExceptionControleur(ExceptionProgrammeExemple.TYPE_CONTROLEUR_ECRAN,"Une erreur inattendue est survenue"));	
			
		}
		
		return problemesSaisie;
	}
	
	/**
	 * Execute l'opération PKCS#11 concernée par l'écran de saisie (opération liée à la session)
	 * @param application L'application
	 * @param saisie L'écran de saisie
	 * @throws ExceptionProgrammeExemple
	 */
	private static void executeOperationP11Sessions(Application application, Saisie saisie) throws ExceptionProgrammeExemple {

		Resultat resultat = null;
		
		switch(saisie.getType()) {

			case EcranUtil.TYPE_ECRAN_INIT_CODE_PORTEUR:
				
				// > INITIALISATION DU CODE PORTEUR
				if(application.getSessionCourante() != null 
						&& ((Saisie2PIN)saisie).getPIN() != null 
							&& ((Saisie2PIN)saisie).getPIN2() != null 
								&& new String(((Saisie2PIN)saisie).getPIN()).equalsIgnoreCase(new String(((Saisie2PIN)saisie).getPIN2()))) {
					
					resultat = InitPIN.traitementP11(application.getLibrairieP11(), application.getSessionCourante().getIdSession(),((Saisie2PIN)saisie).getPIN());
					
					// Déclenchement de l'affichage si nécessaire
					if(resultat != null)
						application.declencheAffichageResultat(resultat);
					
				} else {
					log.error("Une erreur inattendue est survenue lors de l'initialisation du code porteur");
					application.notifieException(new ExceptionControleur(ExceptionProgrammeExemple.TYPE_CONTROLEUR_ECRAN,"Une erreur inattendue est survenue"));
				}
				
				break;
			
			case EcranUtil.TYPE_ECRAN_MODIF_CODE_PORTEUR:
				// > MODIFICATION DU CODE PORTEUR
				if(application.getSessionCourante() != null 
						&& ((Saisie3PIN)saisie).getPIN() != null 
							&& ((Saisie3PIN)saisie).getPIN2() != null 
								&& new String(((Saisie3PIN)saisie).getPIN2()).equalsIgnoreCase(new String(((Saisie3PIN)saisie).getPIN3()))) {
					
					resultat = ModifPIN.traitementP11(application.getLibrairieP11(), application.getSessionCourante().getIdSession(),((Saisie3PIN)saisie).getPIN(),((Saisie3PIN)saisie).getPIN2());
					
					// Déclenchement de l'affichage si nécessaire
					if(resultat != null)
						application.declencheAffichageResultat(resultat);
					
				} else {
					log.error("Une erreur inattendue est survenue lors de la modification du code porteur");
					application.notifieException(new ExceptionControleur(ExceptionProgrammeExemple.TYPE_CONTROLEUR_ECRAN,"Une erreur inattendue est survenue"));
				}
				break;	

			// > S'AUTHENTIFIER UTILISATEUR
			case EcranUtil.TYPE_ECRAN_AUTHENTIFICATION_UTILISATEUR:
				if(application.getSessionCourante() != null && ((Saisie1PIN)saisie).getPIN() != null) {
					
					resultat = Authentifier.traitementP11(application.getLibrairieP11(), application.getSessionCourante().getIdSession(),((Saisie1PIN)saisie).getPIN(),false);
					// Déclenchement de l'affichage si nécessaire
					if(resultat != null)
						application.declencheAffichageResultat(resultat);
					// MAJ Menus
					if(resultat != null && resultat.getCodeRetourStr() != null && resultat.getCodeRetourStr().startsWith("CKR_OK")) {
						application.getSessionCourante().chargeInfo(application.getLibrairieP11());
						MenuControleur.refresh(application, MenuApplication.P11_SESSIONS_AUTHENT_UTILISATEUR);
					}
					
				} else {
					log.error("Une erreur inattendue est survenue lors de l'authentification de l'utilisateur");
					application.notifieException(new ExceptionControleur(ExceptionProgrammeExemple.TYPE_CONTROLEUR_ECRAN,"Une erreur inattendue est survenue"));					
				}
				break;

			// > S'AUTHENTIFIER SO
			case EcranUtil.TYPE_ECRAN_AUTHENTIFICATION_SO:
				if(application.getSessionCourante() != null && ((Saisie1PIN)saisie).getPIN() != null) {
					
					resultat = Authentifier.traitementP11(application.getLibrairieP11(), application.getSessionCourante().getIdSession(),((Saisie1PIN)saisie).getPIN(),true);
					// Déclenchement de l'affichage si nécessaire
					if(resultat != null)
						application.declencheAffichageResultat(resultat);
					// MAJ Menus
					if(resultat != null && resultat.getCodeRetourStr() != null && resultat.getCodeRetourStr().startsWith("CKR_OK")) {
						application.getSessionCourante().chargeInfo(application.getLibrairieP11());
						MenuControleur.refresh(application, MenuApplication.P11_SESSIONS_AUTHENT_SO);
					}
					
				} else {
					log.error("Une erreur inattendue est survenue lors de l'authentification du Security Officer (SO)");
					application.notifieException(new ExceptionControleur(ExceptionProgrammeExemple.TYPE_CONTROLEUR_ECRAN,"Une erreur inattendue est survenue"));					
				}
				break;
				
			default:
				log.error("Type d'écran inconnu");
				throw new ExceptionControleur(ExceptionProgrammeExemple.TYPE_CONTROLEUR_ECRAN,"Une erreur inattendue est survenue");
			
		}
		
	}
	
	/**
	 * Execute l'opération PKCS#11 concernée par l'écran de saisie (opération liée aux objets)
	 * @param application L'application
	 * @param saisie L'écran de saisie
	 * @throws ExceptionProgrammeExemple
	 */
	private static void executeOperationP11Objets(Application application, Saisie saisie) throws ExceptionProgrammeExemple {

		Resultat resultat = null;
		
		switch(saisie.getType()) {

			// > CREER L'OBJET DE DONNEES APPLICATIVES
			case EcranUtil.TYPE_ECRAN_CREATION_OBJETS:
				if(application.getSessionCourante() != null && ((SaisieObjet)saisie).getLibelleObjet() != null && ((SaisieObjet)saisie).getObjet() != null) {
					resultat = CreerObjet.traitementP11(application.getLibrairieP11(), application.getSessionCourante().getIdSession(),((SaisieObjet)saisie).getLibelleObjet(),((SaisieObjet)saisie).getObjet());
					// Déclenchement de l'affichage si nécessaire
					if(resultat != null)
						application.declencheAffichageResultat(resultat);
					// MAJ Menus
					// Pour mettre à jour la liste des objets on fait une recherche des objets de données applicatives
					if(resultat != null && resultat.getCodeRetourStr() != null && resultat.getCodeRetourStr().startsWith("CKR_OK")) {
						TraitementsUtil.rechercheObjets(application, TraitementsUtil.TYPE_OBJET_DONNEES_APPLICATIVES, ((SaisieObjet)saisie).getLibelleObjet(), false);
					}
					
				} else {
					log.error("Une erreur inattendue est survenue lors de la tentative de creation de l'objet");
					application.notifieException(new ExceptionControleur(ExceptionProgrammeExemple.TYPE_CONTROLEUR_ECRAN,"Une erreur inattendue est survenue"));					
				}
				break;
				
			// > MODIFIER L'OBJET DE DONNEES APPLICATIVES
			case EcranUtil.TYPE_ECRAN_MODIFICATION_OBJETS:
				if(application.getSessionCourante() != null && ((SaisieObjet)saisie).getLibelleObjet() != null && ((SaisieObjet)saisie).getObjet() != null) {
					resultat = ModificationAttributObjet.traitementP11(application.getLibrairieP11(), application.getSessionCourante().getIdSession(), ((SaisieObjet)saisie).getIdObjet(), ((SaisieObjet)saisie).getLibelleObjet(),((SaisieObjet)saisie).getObjet());
					// Déclenchement de l'affichage si nécessaire
					if(resultat != null)
						application.declencheAffichageResultat(resultat);
					// MAJ Menus
					// Pour mettre à jour la liste des objets on fait une recherche des objets de données applicatives
					if(resultat != null && resultat.getCodeRetourStr() != null && resultat.getCodeRetourStr().startsWith("CKR_OK")) {
						TraitementsUtil.rechercheObjets(application, TraitementsUtil.TYPE_OBJET_DONNEES_APPLICATIVES, ((SaisieObjet)saisie).getLibelleObjet(), false);
					}
				} else {
					log.error("Une erreur inattendue est survenue lors de la tentative de modification de l'objet");
					application.notifieException(new ExceptionControleur(ExceptionProgrammeExemple.TYPE_CONTROLEUR_ECRAN,"Une erreur inattendue est survenue"));					
				}
				break;

			// > RECHERCHER L'OBJET DE DONNEES APPLICATIVES
			case EcranUtil.TYPE_ECRAN_RECHERCHE_OBJETS:
				if(application.getSessionCourante() != null) {
					// raz des filtres d'objets
					application.supprimeTousLesFiltresObjets();
					resultat = TraitementsUtil.rechercheObjets(application, TraitementsUtil.TYPE_OBJET_DONNEES_APPLICATIVES, ((SaisieFiltreObjet)saisie).getFiltre(), true);
					// Déclenchement de l'affichage si nécessaire
					if(resultat != null) {
						application.declencheAffichageResultat(resultat);
					}
				} else {
					log.error("Une erreur inattendue est survenue lors de la tentative de recherche d'objets de données applicatives");
					application.notifieException(new ExceptionControleur(ExceptionProgrammeExemple.TYPE_CONTROLEUR_ECRAN,"Une erreur inattendue est survenue"));					
				}
				break;
				
				
			default:
				log.error("Type d'écran inconnu");
				throw new ExceptionControleur(ExceptionProgrammeExemple.TYPE_CONTROLEUR_ECRAN,"Une erreur inattendue est survenue");
		
		}
		
	}		

	/**
	 * Execute l'opération PKCS#11 concernée par l'écran de saisie (opération liée à la génération d'empreinte)
	 * @param application L'application
	 * @param saisie L'écran de saisie
	 * @throws ExceptionProgrammeExemple
	 */
	private static void executeOperationP11Empreintes(Application application, Saisie saisie) throws ExceptionProgrammeExemple {

		Resultat resultat = null;
		
		switch(saisie.getType()) {

			// > GENERER EMPREINTE MESSAGE COURT
			case EcranUtil.TYPE_ECRAN_GENERATION_EMPREINTE_MESSAGE:
				if(application.getSessionCourante() != null && ((SaisieMessage)saisie).getMessage() != null && ((SaisieMessage)saisie).getAlgo() != null) {
					resultat = GenererEmpreinteMessage.traitementP11(application.getLibrairieP11(), application.getSessionCourante().getIdSession(),((SaisieMessage)saisie).getAlgo().getIdAlgo(),((SaisieMessage)saisie).getMessage());
					// Déclenchement de l'affichage si nécessaire
					if(resultat != null)
						application.declencheAffichageResultat(resultat);
				} else {
					log.error("Une erreur inattendue est survenue lors de la tentative de generation de l'empreinte de message");
					application.notifieException(new ExceptionControleur(ExceptionProgrammeExemple.TYPE_CONTROLEUR_ECRAN,"Une erreur inattendue est survenue"));					
				}
				break;
	
			// > GENERER EMPREINTE FICHIER
			case EcranUtil.TYPE_ECRAN_GENERATION_EMPREINTE_FICHIER:
				if(application.getSessionCourante() != null && ((SaisieFichier)saisie).getFichier() != null && ((SaisieFichier)saisie).getAlgo() != null) {
					FileInputStream fis = null;
					try {
						fis = new FileInputStream(new File(((SaisieFichier)saisie).getFichier()));
						resultat = GenererEmpreinteFichier.traitementP11(application.getLibrairieP11(), application.getSessionCourante().getIdSession(),((SaisieFichier)saisie).getAlgo().getIdAlgo(),fis);
						if(fis != null)
							fis.close();
						// Déclenchement de l'affichage si nécessaire
						if(resultat != null)
							application.declencheAffichageResultat(resultat);
					} catch (FileNotFoundException e) {
						log.error("Une erreur fichier est survenue lors de la tentative de generation de l'empreinte de fichier : "+ExceptionProgrammeExemple.getStacktrace(e));
						application.notifieException(new ExceptionControleur(ExceptionProgrammeExemple.TYPE_CONTROLEUR_ECRAN,"Une erreur inattendue est survenue"));
					} catch (IOException e) {
						log.error("Une erreur fichier est survenue lors de la tentative de generation de l'empreinte de fichier : "+ExceptionProgrammeExemple.getStacktrace(e));
						application.notifieException(new ExceptionControleur(ExceptionProgrammeExemple.TYPE_CONTROLEUR_ECRAN,"Une erreur inattendue est survenue"));
					}
				} else {
					log.error("Une erreur inattendue est survenue lors de la tentative de generation de l'empreinte de fichier");
					application.notifieException(new ExceptionControleur(ExceptionProgrammeExemple.TYPE_CONTROLEUR_ECRAN,"Une erreur inattendue est survenue"));					
				}
				break;
				
			default:
				log.error("Type d'écran inconnu");
				throw new ExceptionControleur(ExceptionProgrammeExemple.TYPE_CONTROLEUR_ECRAN,"Une erreur inattendue est survenue");
		
		}
		
	}
	
	/**
	 * Execute l'opération PKCS#11 concernée par l'écran de saisie (opération liée à la génération de signature)
	 * @param application L'application
	 * @param saisie L'écran de saisie
	 * @throws ExceptionProgrammeExemple 
	 */
	private static void executeOperationP11Signatures(Application application, Saisie saisie) throws ExceptionProgrammeExemple {

		Resultat resultat = null;
		
		switch(saisie.getType()) {

			// > GENERER SIGNATURE MESSAGE COURT
			case EcranUtil.TYPE_ECRAN_GENERATION_SIGNATURE_MESSAGE:
				if(application.getSessionCourante() != null 
						&& ((SaisieMessage)saisie).getMessage() != null 
							&& ((SaisieMessageSignature)saisie).getAlgo() != null 
								&& ((SaisieMessageSignature)saisie).getCle() != null) {
					
					// Réinitialisation
					application.setMessageSigne(null);
					application.setSignatureMessage(null);							
					
					// Signature
					resultat = GenererSignatureMessage.traitementP11(application.getLibrairieP11(), application.getSessionCourante().getIdSession(), ((SaisieMessage)saisie).getAlgo().getIdAlgo(), ((SaisieMessageSignature)saisie).getCle().getIdCle(), ((SaisieMessage)saisie).getMessage());
					// Déclenchement de l'affichage si nécessaire
					if(resultat != null)
						application.declencheAffichageResultat(resultat);
					// MAJ Menus
					// sauvegarde du message à signer et de la signature du message
					if(resultat != null && resultat.getCodeRetourStr() != null && resultat.getCodeRetourStr().startsWith("CKR_OK") && resultat != null && ((ResultatSignatureMessage)resultat).getCodeRetour2().startsWith("CKR_OK")) {
						application.setMessageSigne(((SaisieMessage)saisie).getMessage());
						application.setSignatureMessage(((ResultatSignatureMessage)resultat).getSignature());
					}
					
				} else {
					log.error("Une erreur inattendue est survenue lors de la tentative de generation de la signature du message");
					application.notifieException(new ExceptionControleur(ExceptionProgrammeExemple.TYPE_CONTROLEUR_ECRAN,"Une erreur inattendue est survenue"));					
				}
				break;
	
			// > GENERER SIGNATURE FICHIER
			case EcranUtil.TYPE_ECRAN_GENERATION_SIGNATURE_FICHIER:
				if(application.getSessionCourante() != null
						&& ((SaisieFichier)saisie).getFichier() != null
							&& ((SaisieFichierSignature)saisie).getAlgo() != null
								&& ((SaisieFichierSignature)saisie).getCle() != null) {
					FileInputStream fis = null;
					try {
						
						// Réinitialisation
						application.setFichierSigne(null);
						application.setSignatureFichier(null);
						
						// Signature
						fis = new FileInputStream(new File(((SaisieFichier)saisie).getFichier()));
						resultat = GenererSignatureFichier.traitementP11(application.getLibrairieP11(), application.getSessionCourante().getIdSession(), ((SaisieFichier)saisie).getAlgo().getIdAlgo(), ((SaisieFichierSignature)saisie).getCle().getIdCle(), fis);
						if(fis != null)
							fis.close();
						// Déclenchement de l'affichage si nécessaire
						if(resultat != null)
							application.declencheAffichageResultat(resultat);
						// MAJ Menus
						// Sauvegarde du fichier à signer et de la signature du fichier
						if(resultat != null && resultat.getCodeRetourStr() != null && resultat.getCodeRetourStr().startsWith("CKR_OK") && resultat != null 
												&& ((ResultatSignatureFichier)resultat).getCodeRetour2().startsWith("CKR_OK")
													&& ((ResultatSignatureFichier)resultat).getCodeRetour3().startsWith("CKR_OK")) {
							application.setFichierSigne(((SaisieFichier)saisie).getFichier());
							application.setSignatureFichier(((ResultatSignatureFichier)resultat).getSignature());
						}
						
					} catch (FileNotFoundException e) {
						log.error("Une erreur fichier est survenue lors de la tentative de generation de la signature du fichier : "+ExceptionProgrammeExemple.getStacktrace(e));
						application.notifieException(new ExceptionControleur(ExceptionProgrammeExemple.TYPE_CONTROLEUR_ECRAN,"Une erreur inattendue est survenue"));
					} catch (IOException e) {
						log.error("Une erreur fichier est survenue lors de la tentative de generation de la signature du fichier : "+ExceptionProgrammeExemple.getStacktrace(e));
						application.notifieException(new ExceptionControleur(ExceptionProgrammeExemple.TYPE_CONTROLEUR_ECRAN,"Une erreur inattendue est survenue"));
					}
				} else {
					log.error("Une erreur inattendue est survenue lors de la tentative de generation de la signature du fichier");
					application.notifieException(new ExceptionControleur(ExceptionProgrammeExemple.TYPE_CONTROLEUR_ECRAN,"Une erreur inattendue est survenue"));					
				}
				break;
				
			default:
				log.error("Type d'écran inconnu");
				throw new ExceptionControleur(ExceptionProgrammeExemple.TYPE_CONTROLEUR_ECRAN,"Une erreur inattendue est survenue");
		
		}
		
	}
	
	/**
	 * Execute l'opération PKCS#11 concernée par l'écran de saisie (opération liée à la vérification de signature)
	 * @param application L'application
	 * @param saisie L'écran de saisie
	 * @throws ExceptionProgrammeExemple
	 */
	private static void executeOperationP11Verifications(Application application, Saisie saisie) throws ExceptionProgrammeExemple {

		Resultat resultat = null;
		
		switch(saisie.getType()) {

			// > VERIFICATION DE SIGNATURE DU MESSAGE COURT
			case EcranUtil.TYPE_ECRAN_VERIFICATION_SIGNATURE_MESSAGE:
				if(application.getSessionCourante() != null 
						&& ((SaisieMessage)saisie).getMessage() != null
							&& ((SaisieMessageSignature)saisie).getAlgo() != null
								&& ((SaisieMessageSignature)saisie).getSignature() != null 
									&& ((SaisieMessageSignature)saisie).getCle() != null) {
					
					// Verification de signature
					resultat = VerifierSignatureMessage.traitementP11(application.getLibrairieP11(), 
																	  	application.getSessionCourante().getIdSession(), 
																	  		((SaisieMessage)saisie).getAlgo().getIdAlgo(), 
																	  			((SaisieMessageSignature)saisie).getCle().getIdCle(), 
																	  				((SaisieMessage)saisie).getMessage(),
																	  					((SaisieMessageSignature)saisie).getSignature());
					// Déclenchement de l'affichage si nécessaire
					if(resultat != null)
						application.declencheAffichageResultat(resultat);

				} else {
					log.error("Une erreur inattendue est survenue lors de la tentative de verification de la signature du message");
					application.notifieException(new ExceptionControleur(ExceptionProgrammeExemple.TYPE_CONTROLEUR_ECRAN,"Une erreur inattendue est survenue"));					
				}
				break;
	
			// > VERIFICATION DE SIGNATURE DU FICHIER
			case EcranUtil.TYPE_ECRAN_VERIFICATION_SIGNATURE_FICHIER:
				if(application.getSessionCourante() != null
						&& ((SaisieFichier)saisie).getFichier() != null
							&& ((SaisieFichierSignature)saisie).getAlgo() != null
								&& ((SaisieFichierSignature)saisie).getSignature() != null
									&& ((SaisieFichierSignature)saisie).getCle() != null) {
					FileInputStream fis = null;
					try {
	
						
						// Verification de signature
						fis = new FileInputStream(new File(((SaisieFichier)saisie).getFichier()));
						resultat = VerifierSignatureFichier.traitementP11(application.getLibrairieP11(), 
																			application.getSessionCourante().getIdSession(), 
																				((SaisieFichier)saisie).getAlgo().getIdAlgo(), 
																					((SaisieFichierSignature)saisie).getCle().getIdCle(), 
																						fis,
																						((SaisieFichierSignature)saisie).getSignature());
	
						if(fis != null)
							fis.close();
	
						// Déclenchement de l'affichage si nécessaire
						if(resultat != null)
							application.declencheAffichageResultat(resultat);
						
					} catch (FileNotFoundException e) {
						log.error("Une erreur fichier est survenue lors de la tentative de verification de la signature du fichier : "+ExceptionProgrammeExemple.getStacktrace(e));
						application.notifieException(new ExceptionControleur(ExceptionProgrammeExemple.TYPE_CONTROLEUR_ECRAN,"Une erreur inattendue est survenue"));
					} catch (IOException e) {
						log.error("Une erreur fichier est survenue lors de la tentative de verification de la signature du fichier : "+ExceptionProgrammeExemple.getStacktrace(e));
						application.notifieException(new ExceptionControleur(ExceptionProgrammeExemple.TYPE_CONTROLEUR_ECRAN,"Une erreur inattendue est survenue"));
					}
				} else {
					log.error("Une erreur inattendue est survenue lors de la tentative de verification de la signature du fichier");
					application.notifieException(new ExceptionControleur(ExceptionProgrammeExemple.TYPE_CONTROLEUR_ECRAN,"Une erreur inattendue est survenue"));					
				}
				break;
				
			default:
				log.error("Type d'écran inconnu");
				throw new ExceptionControleur(ExceptionProgrammeExemple.TYPE_CONTROLEUR_ECRAN,"Une erreur inattendue est survenue");
		
		}
		
	}
	
	/**
	 * Execute l'opération PKCS#11 concernée par l'écran de saisie (opération liée à la génération de nombre pseudo-aléatoire)
	 * @param application L'application
	 * @param saisie L'écran de saisie
	 * @throws ExceptionProgrammeExemple
	 */
	private static void executeOperationP11GenerationAleatoire(Application application, Saisie saisie) throws ExceptionProgrammeExemple {

		Resultat resultat = null;
		
		switch(saisie.getType()) {
		
			case EcranUtil.TYPE_ECRAN_GENERATION_AVEC_SEED:
				// > AVEC SEED
				if(application.getSessionCourante() != null && ((SaisieSeed)saisie).getSeed() != null) {
					resultat = GenerationSeed.traitementP11(application.getLibrairieP11(), application.getSessionCourante().getIdSession(),((SaisieSeed)saisie).getSeed());
					// Déclenchement de l'affichage si nécessaire
					if(resultat != null)
						application.declencheAffichageResultat(resultat);
				} else {
					log.error("Une erreur inattendue est survenue lors de la tentative de generation de nombre pseudo-aleatoire couplée à une graine (seed)");
					application.notifieException(new ExceptionControleur(ExceptionProgrammeExemple.TYPE_CONTROLEUR_ECRAN,"Une erreur inattendue est survenue"));					
				}
				break;
				
			default:
				log.error("Type d'écran inconnu");
				throw new ExceptionControleur(ExceptionProgrammeExemple.TYPE_CONTROLEUR_ECRAN,"Une erreur inattendue est survenue");
				
		}
		
	}


	/**
	 * Valide la saisie d'un écran de test de fonction PKCS#11 liée à la session
	 * @param application L'application
	 * @param saisie L'écran de saisie
	 * @return Liste des problèmes de saisie
	 * @throws ExceptionControleur 
	 */
	private static Vector<String> valideSaisieP11Sessions(Application application, Saisie saisie) throws ExceptionControleur {

		Vector<String> problemesSaisie = new Vector<String>();
		
		switch(saisie.getType()) {

			// > INITIALISATION DU CODE PORTEUR
			case EcranUtil.TYPE_ECRAN_INIT_CODE_PORTEUR:
				
				if(((Saisie2PIN)saisie).getPIN() == null || ((Saisie2PIN)saisie).getPIN().length == 0
						|| ((Saisie2PIN)saisie).getPIN2() == null || ((Saisie2PIN)saisie).getPIN2().length == 0)
					problemesSaisie.add("Les 2 codes PIN doivent être renseignés");
				
				if(((Saisie2PIN)saisie).getPIN() != null && !(new String(((Saisie2PIN)saisie).getPIN()).equalsIgnoreCase(new String(((Saisie2PIN)saisie).getPIN2()))))
					problemesSaisie.add("Les 2 codes PIN doivent être identiques");

				break;
			
			// > MODIFICATION DU CODE PORTEUR
			case EcranUtil.TYPE_ECRAN_MODIF_CODE_PORTEUR:

				if(((Saisie3PIN)saisie).getPIN() == null || ((Saisie3PIN)saisie).getPIN().length == 0
						|| ((Saisie3PIN)saisie).getPIN2() == null || ((Saisie3PIN)saisie).getPIN2().length == 0
						|| ((Saisie3PIN)saisie).getPIN3() == null || ((Saisie3PIN)saisie).getPIN3().length == 0)
					problemesSaisie.add("Les 3 codes PIN doivent être renseignés");
				
				if(((Saisie3PIN)saisie).getPIN2() != null && !(new String(((Saisie3PIN)saisie).getPIN2()).equalsIgnoreCase(new String(((Saisie3PIN)saisie).getPIN3()))))
					problemesSaisie.add("Les 2 nouveaux codes PIN doivent être identiques");

				break;	

			// > S'AUTHENTIFIER UTILISATEUR
			case EcranUtil.TYPE_ECRAN_AUTHENTIFICATION_UTILISATEUR:

				if(((Saisie1PIN)saisie).getPIN() == null || ((Saisie1PIN)saisie).getPIN().length == 0)
					problemesSaisie.add("Le code PIN doit être renseigné");
				
				break;

			// > S'AUTHENTIFIER SO
			case EcranUtil.TYPE_ECRAN_AUTHENTIFICATION_SO:

				if(((Saisie1PIN)saisie).getPIN() == null || ((Saisie1PIN)saisie).getPIN().length == 0)
					problemesSaisie.add("Le code PUK doit être renseigné");
				
				break;
				
			default:
				log.error("Type d'écran inconnu");
				throw new ExceptionControleur(ExceptionProgrammeExemple.TYPE_CONTROLEUR_ECRAN,"Une erreur inattendue est survenue");
			
		}
		
		return problemesSaisie;
		
	}
	
	/**
	 * Valide la saisie d'un écran de test de fonction PKCS#11 liée aux objets
	 * @param application L'application
	 * @param saisie L'écran de saisie
	 * @return Liste des problèmes de saisie
	 * @throws ExceptionControleur 
	 */
	private static Vector<String> valideSaisieP11Objets(Application application, Saisie saisie) throws ExceptionControleur {

		Vector<String> problemesSaisie = new Vector<String>();
		
		switch(saisie.getType()) {

			// > CREER L'OBJET DE DONNEES APPLICATIVES
			case EcranUtil.TYPE_ECRAN_CREATION_OBJETS:
			// > MODIFIER L'OBJET DE DONNEES APPLICATIVES
			case EcranUtil.TYPE_ECRAN_MODIFICATION_OBJETS:
				
				if(((SaisieObjet)saisie).getLibelleObjet() == null || ((SaisieObjet)saisie).getLibelleObjet().length() == 0)
					problemesSaisie.add("Le libellé de l'objet doit être renseigné");				

				if(((SaisieObjet)saisie).getObjet() == null || ((SaisieObjet)saisie).getObjet().length() == 0)
					problemesSaisie.add("Les données de l'objet doivent être renseignées");				
				
				break;
				
			default:
				log.error("Type d'écran inconnu");
				throw new ExceptionControleur(ExceptionProgrammeExemple.TYPE_CONTROLEUR_ECRAN,"Une erreur inattendue est survenue");
		
		}
		
		return problemesSaisie;
		
	}		

	/**
	 * Valide la saisie d'un écran de test de fonction PKCS#11 liée à la génération d'empreinte
	 * @param application L'application
	 * @param saisie L'écran de saisie
	 * @return Liste des problèmes de saisie
	 * @throws ExceptionTraitement
	 * @throws ExceptionControleur 
	 */
	private static Vector<String> valideSaisieP11Empreintes(Application application, Saisie saisie) throws ExceptionTraitement, ExceptionControleur {

		Vector<String> problemesSaisie = new Vector<String>();
		
		switch(saisie.getType()) {

			// > GENERER EMPREINTE MESSAGE COURT
			case EcranUtil.TYPE_ECRAN_GENERATION_EMPREINTE_MESSAGE:

				if(((SaisieMessage)saisie).getAlgo() == null)
					problemesSaisie.add("Un algorithme doit être sélectionné");
				
				if(((SaisieMessage)saisie).getMessage() == null || ((SaisieMessage)saisie).getMessage().length == 0)
					problemesSaisie.add("Le message doit être renseigné");	
				
				break;
	
			// > GENERER EMPREINTE FICHIER
			case EcranUtil.TYPE_ECRAN_GENERATION_EMPREINTE_FICHIER:

				if(((SaisieFichier)saisie).getAlgo() == null)
					problemesSaisie.add("Un algorithme doit être sélectionné");				
				
				if(((SaisieFichier)saisie).getFichier() == null || ((SaisieFichier)saisie).getFichier().length() == 0)
					problemesSaisie.add("Un fichier doit être choisi");
				
				break;
				
			default:
				log.error("Type d'écran inconnu");
				throw new ExceptionControleur(ExceptionProgrammeExemple.TYPE_CONTROLEUR_ECRAN,"Une erreur inattendue est survenue");
		
		}
		
		return problemesSaisie;
		
	}
	
	/**
	 * Valide la saisie d'un écran de test de fonction PKCS#11 liée à la génération de signature
	 * @param application L'application
	 * @param saisie L'écran de saisie
	 * @return Liste des problèmes de saisie
	 * @throws ExceptionTraitement
	 * @throws ExceptionControleur 
	 */
	private static Vector<String> valideSaisieP11Signatures(Application application, Saisie saisie) throws ExceptionTraitement, ExceptionControleur {

		Vector<String> problemesSaisie = new Vector<String>();
		
		switch(saisie.getType()) {

			// > GENERER SIGNATURE MESSAGE COURT
			case EcranUtil.TYPE_ECRAN_GENERATION_SIGNATURE_MESSAGE:
				
				if(((SaisieMessageSignature)saisie).getAlgo() == null)
					problemesSaisie.add("Un algorithme doit être sélectionné");
				
				if(((SaisieMessageSignature)saisie).getMessage() == null || ((SaisieMessageSignature)saisie).getMessage().length == 0)
					problemesSaisie.add("Le message doit être renseigné");	

				if(((SaisieMessageSignature)saisie).getCle() == null)
					problemesSaisie.add("Une clé doit être sélectionnée");
				
				break;
	
			// > GENERER SIGNATURE FICHIER
			case EcranUtil.TYPE_ECRAN_GENERATION_SIGNATURE_FICHIER:
				
				if(((SaisieFichierSignature)saisie).getAlgo() == null)
					problemesSaisie.add("Un algorithme doit être sélectionné");
				
				if(((SaisieFichierSignature)saisie).getFichier() == null || ((SaisieFichierSignature)saisie).getFichier().length() == 0)
					problemesSaisie.add("Un fichier doit être choisi");	

				if(((SaisieFichierSignature)saisie).getCle() == null)
					problemesSaisie.add("Une clé doit être sélectionnée");
				
				break;
				
			default:
				log.error("Type d'écran inconnu");
				throw new ExceptionControleur(ExceptionProgrammeExemple.TYPE_CONTROLEUR_ECRAN,"Une erreur inattendue est survenue");
		
		}
		
		return problemesSaisie;
		
	}
	
	/**
	 * Valide la saisie d'un écran de test de fonction PKCS#11 liée à la vérification de signature
	 * @param application L'application
	 * @param saisie L'écran de saisie
	 * @return Liste des problèmes de saisie
	 * @throws ExceptionControleur 
	 */
	private static Vector<String> valideSaisieP11Verifications(Application application, Saisie saisie) throws ExceptionControleur {

		Vector<String> problemesSaisie = new Vector<String>();
		
		switch(saisie.getType()) {

			// > VERIFICATION DE SIGNATURE DU MESSAGE COURT
			case EcranUtil.TYPE_ECRAN_VERIFICATION_SIGNATURE_MESSAGE:
				
				if(((SaisieMessageSignature)saisie).getAlgo() == null)
					problemesSaisie.add("Un algorithme doit être sélectionné");
				
				if(((SaisieMessageSignature)saisie).getMessage() == null || ((SaisieMessageSignature)saisie).getMessage().length == 0)
					problemesSaisie.add("Le message doit être renseigné");	

				if(((SaisieMessageSignature)saisie).getSignature() == null || ((SaisieMessageSignature)saisie).getSignature().length() == 0)
					problemesSaisie.add("La signature doit être renseignée");				
				
				if(((SaisieMessageSignature)saisie).getCle() == null)
					problemesSaisie.add("Une clé doit être sélectionnée");

				break;
	
			// > VERIFICATION DE SIGNATURE DU FICHIER
			case EcranUtil.TYPE_ECRAN_VERIFICATION_SIGNATURE_FICHIER:
				
				if(((SaisieFichierSignature)saisie).getAlgo() == null)
					problemesSaisie.add("Un algorithme doit être sélectionné");
				
				if(((SaisieFichierSignature)saisie).getFichier() == null || ((SaisieFichierSignature)saisie).getFichier().length() == 0)
					problemesSaisie.add("Un fichier doit être choisi");

				if(((SaisieFichierSignature)saisie).getSignature() == null || ((SaisieFichierSignature)saisie).getSignature().length() == 0)
					problemesSaisie.add("La signature doit être renseignée");				
				
				if(((SaisieFichierSignature)saisie).getCle() == null)
					problemesSaisie.add("Une clé doit être sélectionnée");
				
				break;
				
			default:
				log.error("Type d'écran inconnu");
				throw new ExceptionControleur(ExceptionProgrammeExemple.TYPE_CONTROLEUR_ECRAN,"Une erreur inattendue est survenue");
		
		}
		
		return problemesSaisie;
		
	}
	
	/**
	 * Valide la saisie d'un écran de test de fonction PKCS#11 liée à la génération de nombre pseudo-aléatoire
	 * @param application L'application
	 * @param saisie L'écran de saisie
	 * @return Liste des problèmes de saisie
	 * @throws ExceptionTraitement
	 * @throws ExceptionControleur 
	 */
	private static Vector<String> valideSaisieP11GenerationAleatoire(Application application, Saisie saisie) throws ExceptionTraitement, ExceptionControleur {

		Vector<String> problemesSaisie = new Vector<String>();
		
		switch(saisie.getType()) {

			// > AVEC SEED
			case EcranUtil.TYPE_ECRAN_GENERATION_AVEC_SEED:
				
				if(((SaisieSeed)saisie).getSeed() == null || ((SaisieSeed)saisie).getSeed().length == 0)
					problemesSaisie.add("La graine (seed) doit être renseignée");					

				break;
				
			default:
				log.error("Type d'écran inconnu");
				throw new ExceptionControleur(ExceptionProgrammeExemple.TYPE_CONTROLEUR_ECRAN,"Une erreur inattendue est survenue");
				
		}
		
		return problemesSaisie;
		
	}	
	
}

